function isOperator(value) {
  let operatorString = "+-*/()";
  return operatorString.indexOf(value) > -1
}

function getPrioraty(value) {
  switch (value) {
    case '+':
    case '-':
      return 1;
    case '*':
    case '/':
      return 2;
    default:
      return 0;
  }
}

function getResult(first, second, operator) {
  let result = 0;
  switch (operator) {
    case '+':
      result = first + second;
      break;
    case '-':
      result = first - second;
      break;
    case '*':
      result = first * second;
      break;
    case '/':
      result = first / second;
      break;
    default:
      return 0;
  }

  //浮点数的小数位超过两位时，只保留两位小数点
  function formatFloat(f, digit) {
    //pow(10,n) 为 10 的 n 次方
    let m = Math.pow(10, digit);
    return parseInt(f * m, 10) / m;
  }

  return (formatFloat(result, 2));
}

function prioraty(o1, o2) {
  return getPrioraty(o1) <= getPrioraty(o2);
}

export function parse(exp) {
  let inputStack = [];
  let outputStack = [];
  let outputQueue = [];
  let str = '';
  for (let i = 0, len = exp.length; i < len; i++) {
    if(!isOperator(exp[i])){
      str += exp[i];
    }else {
      inputStack.push(str);
      inputStack.push(exp[i]);
      str='';
    }
  }
  inputStack.push(str);

  while (inputStack.length > 0) {
    let cur = inputStack.shift();
    if (isOperator(cur)) {
      if (cur == '(') {
        outputStack.push(cur);
      } else if (cur == ')') {
        let po = outputStack.pop();
        while (po != '(' && outputStack.length > 0) {
          outputQueue.push(po);
          po = outputStack.pop();
        }
        if (po != '(') {
          throw "error: unmatched ()";
        }
      } else {
        while (prioraty(cur, outputStack[outputStack.length - 1]) && outputStack.length > 0) {
          outputQueue.push(outputStack.pop());
        }
        outputStack.push(cur);
      }
    } else {

      outputQueue.push(cur);
    }
  }

  if (outputStack.length > 0) {
    if (outputStack[outputStack.length - 1] == ')' || outputStack[outputStack.length - 1] == '(') {
      throw "error: unmatched ()";
    }
    while (outputStack.length > 0) {
      outputQueue.push(outputStack.pop());
    }
  }

  return outputQueue;

}

function evalRpn(rpnQueue, param) {
  //有变量的时候替换变量
  if (param) {
    for (let i = 0; i < rpnQueue.length; i++) {
      if (param[rpnQueue[i]]) {
        rpnQueue[i] = param[rpnQueue[i]];
      }
    }
  }
  if (rpnQueue.length == 1) {
    return rpnQueue[0];
  }
  let outputStack = [];
  while (rpnQueue.length > 0) {
    let cur = rpnQueue.shift();

    if (!isOperator(cur)) {
      outputStack.push(cur);
    } else {
      if (outputStack.length < 2) {
        throw "unvalid stack length";
      }
      let sec = outputStack.pop();
      let fir = outputStack.pop();

      outputStack.push(getResult(fir, sec, cur));
    }
  }

  if (outputStack.length != 1) {
    throw "unvalid expression";
  } else {
    return outputStack[0];
  }
}

export function calculate(exp, param) {
  let parse1 = parse(exp);
  console.log(parse1)
  return evalRpn(parse1, param);
}


